home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / music / eked-m1.zoo / src / midi_com.c < prev    next >
C/C++ Source or Header  |  1995-02-19  |  10KB  |  434 lines

  1. /*
  2.  *  EKED-M1 : Editor for Korg M1 synth; midi_com.c : MIDI communications
  3.  *  Copyright (C) 1995 Steven M. Eker (Steven.Eker@brunel.ac.uk)
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <stddef.h>
  21. #include <osbind.h>
  22. #include <gemfast.h>
  23. #include <aesbind.h>
  24. #include "eked-m1.h"
  25. #include "midi.h"
  26. #include "gm/gem_man.h"
  27. #include "defs.h"
  28. #include "types.h"
  29. #include "externs.h"
  30.  
  31. #define TIME_OUT_REP    50
  32. #define TIME_OUT    (-1)
  33. #define BAD_REPLY    (-2)
  34.  
  35. static BYTE big[7 + PD_SIZE];
  36. static BYTE small[7];
  37. static int global_channel = 0;
  38.  
  39. static enum {
  40.   SYSEX_OFF,
  41.   SYSEX_EXP,
  42.   SYSEX_LIVE
  43. } sysex_mode = SYSEX_LIVE;
  44.  
  45. void midi_opt()
  46. {
  47.   OBJECT *midi_options;
  48.   int channel, t;
  49.  
  50.   rm_gaddr(R_TREE, MIDI_OPTIONS, &midi_options);
  51.   GM_SELECT(sysex_mode == SYSEX_OFF, midi_options, MO_OFF);
  52.   GM_SELECT(sysex_mode == SYSEX_EXP, midi_options, MO_EXP);
  53.   GM_SELECT(sysex_mode == SYSEX_LIVE, midi_options, MO_LIVE);
  54.   channel = global_channel + 1;
  55.   unum_update(midi_options + MO_CHANNEL, channel);
  56.  
  57.   fm_begin_dialog(midi_options, 0);
  58.   do{
  59.     t = fm_run_dialog();
  60.     if(t == MO_CHANNEL)
  61.       channel = fm_roll(midi_options, t, channel, 1, 16, &unum_update);
  62.   }while(t != MO_OK && t != MO_CANCEL);
  63.   fm_end_dialog();
  64.   if(t == MO_CANCEL)
  65.     return;
  66.  
  67.   if(midi_options[MO_OFF].ob_state & SELECTED)
  68.     sysex_mode = SYSEX_OFF;
  69.   else if(midi_options[MO_EXP].ob_state & SELECTED)
  70.     sysex_mode = SYSEX_EXP;
  71.   else
  72.     sysex_mode = SYSEX_LIVE;
  73.   global_channel = channel - 1;
  74. }
  75.  
  76. int midi_comm(int send_bytes, BYTE *send_buf, int rec_bytes, BYTE *rec_buf)
  77. {
  78.   volatile _IOREC *p = Iorec(2);
  79.   int s, d, t;
  80.   BYTE b;
  81.  
  82.   p->ibufhd = p->ibuftl = 0;
  83.   Midiws(send_bytes - 1, send_buf);
  84.  
  85.   t = 0;
  86.   do{
  87.     while(p->ibufhd == p->ibuftl){    /* while buffer empty */
  88.       evnt_timer(20L);    /* wait 20ms - about 63 MIDI bytes */
  89.       if(t++ == TIME_OUT_REP)
  90.         return TIME_OUT;
  91.     }
  92.     s = p->ibufhd + 1;
  93.     if(s >= p->ibufsiz)
  94.       s = 0;
  95.     b = (p->ibuf)[s];
  96.     p->ibufhd = s;
  97.     if(!real_time(b))        /* disregard real time messages */
  98.       t = 0;
  99.   }while(b != (BYTE) SYSEX);    /* until start of sysex message */
  100.   rec_buf[0] = b;
  101.  
  102.   t = 0;
  103.   d = 1;
  104.   do{
  105.     if(d == rec_bytes)    /* reply overran rec_buf */
  106.       return BAD_REPLY;
  107.     while(p->ibufhd == p->ibuftl){    /* while buffer empty */
  108.       evnt_timer(20L);    /* wait 20ms - about 63 MIDI bytes */
  109.       if(t++ == TIME_OUT_REP)
  110.         return TIME_OUT;
  111.     }
  112.     s = p->ibufhd + 1;
  113.     if(s >= p->ibufsiz)
  114.       s = 0;
  115.     b = (p->ibuf)[s];
  116.     p->ibufhd = s;
  117.     if(!real_time(b)){        /* disregard real time messages */
  118.       rec_buf[d++] = b;
  119.       t = 0;
  120.     }
  121.   }while(data_byte(b));        /* until end of sysex message */
  122.  
  123.   return d;
  124. }
  125.  
  126. int m1_sysex(int send_bytes, BYTE *send_buf, int rec_bytes, BYTE *rec_buf)
  127. {
  128.   int t;
  129.  
  130.   send_buf[0] = SYSEX;
  131.   send_buf[1] = KORG_ID;
  132.   send_buf[2] = FORMAT_ID | global_channel;
  133.   send_buf[3] = M1_ID;
  134.   send_buf[send_bytes - 1] = EOX;
  135.   for(;;){
  136.     t = midi_comm(send_bytes, send_buf, rec_bytes, rec_buf);
  137.     if(t == rec_bytes){
  138.       if(rec_buf[4] == DATA_LOAD_ERR)
  139.         t = DATA_LOAD_ALERT;
  140.       else
  141.         break;
  142.     }
  143.     else{
  144.       switch(t){
  145.       case TIME_OUT:
  146.         t = NO_RESPOND_ALERT;
  147.         break;
  148.       case BAD_REPLY:
  149.         t = BAD_REPLY_ALERT;
  150.         break;
  151.       default:
  152.         t = BAD_LEN_ALERT;
  153.       }
  154.     }
  155.     if(fm_alert(1, t) == 2)
  156.       return FAILURE;
  157.   }
  158.   return SUCCESS;
  159. }
  160.  
  161. int tx_bank(BANK *bank, int flags)
  162. {
  163.   int mode;
  164.  
  165.   if(sysex_mode == SYSEX_OFF)
  166.     return FAILURE;
  167.   small[4] = MODE_REQ;
  168.   if(m1_sysex(6, small, 10, big) == FAILURE)
  169.     return FAILURE;
  170.   if(flags & TX_CARD){
  171.     switch(big[7] >> 4){
  172.     case 0:
  173.       fm_alert(1, NO_CARD_ALERT);
  174.       return FAILURE;
  175.     case 1:
  176.       fm_alert(1, ROM_CARD_ALERT);
  177.       return FAILURE;
  178.     case 3:
  179.       fm_alert(1, PROT_CARD_ALERT);
  180.       return FAILURE;
  181.     }
  182.     mode = big[7] & 0x03;
  183.     if(mode == 2){
  184.       fm_alert(1, SEQ_CARD_ALERT);
  185.       return FAILURE;
  186.     }
  187.     big[5] = 1;
  188.   }
  189.   else{
  190.     mode = big[6];
  191.     big[5] = 0;
  192.   }
  193.  
  194.   if(flags & TX_GLOB){
  195.     big[4] = GLOBAL_DATA_DUMP;
  196.     byte2korg(big + 6, bank->data, GLOBAL_SIZE);
  197.     if(m1_sysex(7 + GD_SIZE, big, 6, small) == FAILURE)
  198.       return FAILURE;
  199.   }
  200.   if(flags & TX_COMB){
  201.     big[4] = ALL_COMB_DUMP;
  202.     big[5] |= mode << 1;
  203.     byte2korg(big + 6, bank->data + GLOBAL_SIZE,
  204.               mode ? (50 * COMBINATION_SIZE) : (100 * COMBINATION_SIZE));
  205.     if(m1_sysex(mode ? (7 + CD50_SIZE) : (7 + CD_SIZE), big, 6, small)
  206.        == FAILURE)
  207.       return FAILURE;
  208.   }
  209.   if(flags & TX_PROG){
  210.     big[4] = ALL_PROG_DUMP;
  211.     big[5] |= mode << 1;
  212.     byte2korg(big + 6, bank->data + PROGRAM_OFFSET,
  213.               mode ? (50 * PROGRAM_SIZE) : (100 * PROGRAM_SIZE));
  214.     if(m1_sysex(mode ? (7 + PD50_SIZE) : (7 + PD_SIZE), big, 6, small)
  215.        == FAILURE)
  216.       return FAILURE;
  217.   }
  218.   return SUCCESS;
  219. }
  220.  
  221. int rx_bank(BANK *bank, int flags)
  222. {
  223.   int mode;
  224.  
  225.   if(sysex_mode == SYSEX_OFF)
  226.     return FAILURE;
  227.   small[4] = MODE_REQ;
  228.   if(m1_sysex(6, small, 10, big) == FAILURE)
  229.     return FAILURE;
  230.   if(flags & TX_CARD){
  231.     if(!(big[7] & 0x30)){
  232.       fm_alert(1, NO_CARD_ALERT);
  233.       return FAILURE;
  234.     }
  235.     mode = big[7] & 0x03;
  236.     if(mode == 2){
  237.       fm_alert(1, SEQ_CARD_ALERT);
  238.       return FAILURE;
  239.     }
  240.     small[5] = 1;
  241.   }
  242.   else{
  243.     mode = big[6];
  244.     small[5] = 0;
  245.   }
  246.   if(flags & TX_GLOB){
  247.     small[4] = GLOBAL_DATA_REQ;
  248.     if(m1_sysex(7, small, 7 + GD_SIZE, big) == FAILURE)
  249.       return FAILURE;
  250.     korg2byte(bank->data, big + 6, GLOBAL_SIZE);
  251.   }
  252.   if(flags & TX_COMB){
  253.     small[4] = ALL_COMB_REQ;
  254.     if(m1_sysex(7, small, mode ? (7 + CD50_SIZE) : (7 + CD_SIZE), big)
  255.        == FAILURE)
  256.       return FAILURE;
  257.     korg2byte(bank->data + GLOBAL_SIZE, big + 6,
  258.               mode ? (50 * COMBINATION_SIZE) : (100 * COMBINATION_SIZE));
  259.   }
  260.   if(flags & TX_PROG){
  261.     small[4] = ALL_PROG_REQ;
  262.     if(m1_sysex(7, small, mode ? (7 + PD50_SIZE) : (7 + PD_SIZE), big)
  263.        == FAILURE)
  264.       return FAILURE;
  265.     korg2byte(bank->data + PROGRAM_OFFSET, big + 6,
  266.               mode ? (50 * PROGRAM_SIZE) : (100 * PROGRAM_SIZE));
  267.   }
  268.   return SUCCESS;
  269. }
  270.  
  271. int tx_para_chg(int page, int pos, int value)
  272. {
  273.   if(sysex_mode != SYSEX_LIVE || page < 0)
  274.     return FAILURE;
  275.   big[4] = PARAMETER_CHANGE;
  276.   big[5] = page;
  277.   big[6] = pos;
  278.   big[7] = value & 0x7F;
  279.   big[8] = (value >> 7) & 0x7F;
  280.   return m1_sysex(10, big, 6, small);
  281. }
  282.  
  283. int tx_prog_dmp(BYTE *prog)
  284. {
  285.   if(sysex_mode != SYSEX_LIVE)
  286.     return FAILURE;
  287.   big[4] = PROG_DUMP;
  288.   byte2korg(big + 5, prog, PROGRAM_SIZE);
  289.   return m1_sysex(170, big, 6, small);
  290. }
  291.  
  292. int tx_comb_dmp(BYTE *comb)
  293. {
  294.   if(sysex_mode != SYSEX_LIVE)
  295.     return FAILURE;
  296.   big[4] = COMB_DUMP;
  297.   byte2korg(big + 5, comb, COMBINATION_SIZE);
  298.   return m1_sysex(148, big, 6, small);
  299. }
  300.  
  301. int tx_mode_chg(int mode)
  302. {
  303.   if(sysex_mode != SYSEX_LIVE)
  304.     return FAILURE;
  305.   big[4] = MODE_CHANGE;
  306.   big[5] = mode;
  307.   big[6] = 0x10;
  308.   return m1_sysex(8, big, 6, small);
  309. }
  310.  
  311. void tx_prog_chg(int number)
  312. {
  313.   if(sysex_mode != SYSEX_LIVE)    /* not a sysex but we treat it as such */
  314.     return;
  315. /*
  316.  *    M1 sometimes ignores program change following closely on the heels of 
  317.  *    a sysex so pause for 50ms.
  318.  */
  319.   evnt_timer(50